##%

'''
此程序寻找多个播放列表的重复音乐
将此程序改为面向对象
使用这种叠加，再找出重复的方法，整理明细表
'''


import re, argparse, sys, plistlib
from matplotlib import pyplot
import numpy as np

def find_common_track(file_names):
    """
    提取多个xml文件中相同的音乐
    """
    track_name_sets = []
    
    for g in file_names:
        # set() 函数创建一个无序不重复元素集，可进行关系测试，删除重复数据，还可以计算交集、差集、并集等。
        # 在 Python 中，集合（set）是一种无序且不重复的数据集合。集合是由大括号 {} 包围，其中包含逗号分隔的元素。集合中的元素是不可变的（immutable），这意味着集合中不能包含可变对象（如列表），但可以包含不可变对象（如整数、字符串、元组等）。
        # 在 Python 中，元组（tuple）是一种有序的、不可变的数据结构。与列表（list）类似，元组也可以包含多个元素，但元组的元素不能被修改、删除或添加。元组使用圆括号 () 来表示，其中的元素用逗号 , 分隔。
        # set中不能加入list，tuple中可以加入list，但加入后，tuple内的list不可变
        
        track_name_set = set()  
        # print(type(track_name_set))
        # print(track_name_set)

        with open(g, 'rb') as f:
            plist = plistlib.load(f)
        # plist = plistlib.readPlist(g)
        

        tracks = plist['Tracks'] 
        
        # items()的作用是把字典中的每对key和value组成一个元组，并把这些元祖放在列表中返回。
        for track_id, track in tracks.items():
            # track_id是key, track是value
            # print(track_id)
            # print(track)
            try:
                # set添加元素的方式
                track_name_set.add(track['Name'])
                # track也是字典？
                # 如果有track['name']就添加，没有就忽略
            except:
                pass
        # print(track_name_set)

    # 将多个xml文件的track_name_set，合成一个列表
    track_name_sets.append(track_name_set) 


        # print(track_name_sets)

        # *track_name_sets作用是：将列表元素解开成独立的参数，传入函数。类似的运算符还有两个星号(**)，是将字典解开成独立的元素作为形参。
        # track_name_sets中的各set求交
    common_tracks = set.intersection(*track_name_sets) 

    if len(common_tracks) > 0:
        # f = open('common.txt', 'w', encoding='utf-8')
        with open('common.txt', 'w', encoding='utf-8') as f:
            for v in common_tracks:
                s = f'{v}\n'
                # print(s)
                f.write(s)
            # f.close();
        print(f'找到{len(common_tracks)}首音乐。'\
             '音乐名称已写入common.txt')
    else:
        print('没有音乐！')
        
#%%

def find_dupl(file_name):
    print(f'在{file_name}中寻找重复的歌曲……')

    with open(file_name, 'rb') as f:
        plist = plistlib.load(f)
    
        tracks = plist['Tracks']
        # ic(tracks)       
        track_names = {}            
        for track_id, track in tracks.items():
            try:
                name = track['Name']
                duration = track['Total Time']
                # durations.append(track['Total Time'])

                # track_names是空的，此处还检测name？
                # 字典track_names增加项后再检测
                if name in track_names:

                    # ic(track_names[n])

                    # 如果name在track_names中，再比较时间是否相同
                    # 时间相同，才判断是同一首歌
                    if duration//1000 == track_names[name][0]//1000:
                        count = track_names[name][1]
                        track_names[name] = (duration, count+1)
                else:

                    # 给字典track_names中增加项
                     track_names[name] = (duration,  1)
                # ic(track_names)                       
            except:
                pass
    # ic(track_names)
    
    dups = []
    for k, v in track_names.items():
        if v[1] > 1:
            dups.append(v[1], k)

    if len(dups) > 0:
        print(f'找到{len(dups)}个重复的歌曲，歌曲名保存到dups.txt中。')
    else:
        print('没有找到重复的歌曲。')

    
    with open('dups.txt', 'w') as f:
        for v in dups:
            f.write(f'[{v[0]}] {v[1]}\n')
            
#%%

'''
验证set中的list能否修改
'''

la = [1, 3, 5]
lb = [3, 6, 7]

# cc = {la, lb}

cc = (la, lb)
print(cc)

la = [4,7,6]

print(cc)
print(la)

#%%
def plot_stats(file_name):
    with open(file_name, 'rb') as f:
        plist = plistlib.load(f)
    
    tracks = plist['Tracks'] 

    print(tracks)

    ratings = []
    durations = []
        
    for track_id, track in tracks.items():

        try:
            ratings.append(track['Album Rating'])
            durations.append(track['Total Time'])
        except:
            pass

    if ratings == [] or durations == []:
        print(f'在{file_name}没有符合要求的专辑评分或播放时间。')
        return

    x = np.array(durations, np.int32)

    # 转为分钟?
    x = x / 60000.0

    y = np.array(ratings, np.int32)

    # 散点图
    pyplot.subplot(2, 1, 1)
    pyplot.plot(x, y, 'o')
    pyplot.axis([0, 1.05*np.max(x), -1, 110])
    pyplot.xlabel('音乐时间')
    pyplot.ylabel('音乐评分')

    # 柱状图
    pyplot.subplot(2, 1, 2)
    pyplot.hist(x, bins=20)
    pyplot.xlabel('音乐时间')
    pyplot.ylabel('播放次数')

    pyplot.show()


plot_stats('Library.xml')

#%%

'''
查看系统可用的字体
'''


import matplotlib.font_manager

# 获取系统中所有可用的字体列表
font_list = matplotlib.font_manager.findSystemFonts()

# 打印字体列表
for font_path in font_list:
    font_prop = matplotlib.font_manager.FontProperties(fname=font_path)
    print(font_prop.get_name())
    
    
#%%
def main():
    dec_str = '本程序解析itunes输出的播放列表'

    # 解析器
    parser = argparse.ArgumentParser(description=dec_str)
    
    # 创建了一个互斥组对象 group，用来将一组参数设置为互斥（即只能选择其中一个参数）。
    group = parser.add_mutually_excluisve_group()


    # 分别向互斥组 group 中添加了三个参数：--common、--stats 和 --dup，每个参数都有不同的目标（dest），并且都是可选的（required=False）。
    group.add_argument('--common', nargs='*', dest='plFiles', required=False);
    group.add_argument('--stats', dest='plFile', required=False);
    group.add_argument('--dup', dest='plFileD', required=False);

    # 解析命令行参数，并将结果存储在 args 变量中。
    args = parser.parser_args();


    # 如果用户提供了 --common 参数，则调用 find_common_track 函数处理传入的参数 args.plFiles。
    if args.plFiles:
        find_common_track(args.plFiles)

    elif args.plFile:
        plot_stats(args.plFile)

    elif args.plFileD:
        find_common_track(args.plFileD)

    else:
        print('这些歌曲不是你想找的')